package com.javaedge.concurrency;



class Demo{
    public static void main(String[] args){
        //先运行阻塞的栗子
        /*SynchronizedTest lg = new SynchronizedTest("死锁","老公");
        SynchronizedTest lp = new SynchronizedTest("死锁","老婆");

        lg.start();
        lp.start();*/

        //在运行可重入的栗子
        SynchronizedTest lg = new SynchronizedTest("可重入","老公");
        SynchronizedTest lp = new SynchronizedTest("可重入","老婆");
        lg.start();
        lp.start();
    }
}

/**
 * @Description: .
 * @Author: ZhaoWeiNan .
 * @CreatedTime: 2017/6/25 .
 * @Version: 1.0 .
 */
public class SynchronizedTest extends Thread {

    private String type;

    public SynchronizedTest(String type,String name){
        super(name);
        this.type = type;
    }

    @Override
    public void run() {
        if ("死锁".equals(type)){
            //死锁栗子
            DeadLock();
        }else if ("可重入".equals(type)){
            //可重入栗子
            ReentrantLock();
        }
    }

    /**
     *  一个阻塞的栗子。
     *  1.老公线程，先用西瓜加锁，拿到锁以后，再去用西瓜刀加锁。
     *  2.此时老婆线程已经获取到西瓜刀的锁，然后sleep了。
     *  3.老公线程获取不到西瓜刀的锁，所以被阻塞。
     */
    private void DeadLock(){
        if (Thread.currentThread().getName().equals("老公")){
            synchronized ("西瓜"){
                System.out.println("老公买了西瓜，准备去拿西瓜刀。");
                synchronized("西瓜刀"){
                    System.out.println("老公拿了西瓜刀，准备吃西瓜。");
                }

            }
        }else if (Thread.currentThread().getName().equals("老婆")){
            synchronized ("西瓜刀"){
                System.out.println("老婆把西瓜刀藏起来了，不让老公吃西瓜。");
                try {
                    Thread.sleep(1000000000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 可重入的栗子。
     * 1.老公线程获取了徒手吃西瓜的锁，注意此时，徒手吃西瓜的锁并没有被释放。
     * 2.同时start了一个老婆线程了，徒手吃西瓜的锁并没有被释放，所以老婆线程没有获取到徒手吃西瓜锁。
     * 3.老公线程再次获取徒手吃西瓜的锁，没有被阻塞，证明了synchronized的可重入。
     */
    private void ReentrantLock(){
        if (Thread.currentThread().getName().equals("老公")){
            synchronized ("徒手吃西瓜"){
                System.out.println("老公买了西瓜，徒手掰西瓜。");
                synchronized("徒手吃西瓜"){
                    System.out.println("老公掰开了西瓜，准备吃西瓜。");
                    System.out.println("老公把老婆锁在外面，吃完西瓜才让她进来。");
                    try {
                        Thread.sleep(1000000000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }else if (Thread.currentThread().getName().equals("老婆")){
            System.out.println("老婆冲进家。");
            synchronized ("徒手吃西瓜"){
                System.out.println("老婆抓住老公的手，不让老公吃西瓜。");
            }
        }


    }
}
